home *** CD-ROM | disk | FTP | other *** search
/ HyperLib 1997 Winter - Disc 1 / HYPERLIB-1997-Winter-CD1.ISO.7z / HYPERLIB-1997-Winter-CD1.ISO / オンラインウェア / PRG / SysMenu 1.4 Folder.sit / SysMenu 1.4 Folder / SysMenu 1.4 / INIT Dispatcher.c < prev    next >
C/C++ Source or Header  |  1996-04-20  |  5KB  |  145 lines

  1. // File "INIT Dispatcher.c" - Sample source that shows one way to make FAT INIT resources.
  2. //   Original source by Matt Slot (fprefect@umich.edu) - 7/3/95
  3. //   Changes from 1.1 to 1.2 - 1/20/96
  4. //       * Fixed the Gestalt call to to gracefully accept an error code on 68K
  5. //         systems that simply doesn't know about the new selector.
  6. //   Changes from 1.2 to 1.3 - 4/20/96
  7. //       * Updated for CW8
  8. //       * Removed test for PPC 620
  9. //       * Better ResError checking
  10.  
  11.  
  12. #include <A4Stuff.h>
  13. #include <CodeFragments.h>
  14. #include <Gestalt.h>
  15. #include <MixedMode.h>
  16.  
  17. //#define ____DEBUG____
  18. #define k68KProcType    '68K・'
  19. #define kPPCProcType    'PPC・'
  20.  
  21. // * ******************************************************************************* *
  22. // * ******************************************************************************* *
  23.  
  24. typedef pascal void (*INITProcPtr)(void);
  25. enum {
  26.     uppINITProcInfo = kPascalStackBased
  27.     };
  28. #define CallINITProc(proc) (* ((INITProcPtr) proc))()
  29.  
  30. // * ******************************************************************************* *
  31. // * ******************************************************************************* *
  32. // Function Prototypes
  33.  
  34. void __Startup__(void);
  35. void main(void);
  36.  
  37. // * ******************************************************************************* *
  38. // * ******************************************************************************* *
  39. // Incredibly Important! - This file must be the first in the segment, and this
  40. //   function must be the first one in it... defining the custom resource header.
  41. //   Here, we can use high level language to call our *real* main.
  42.  
  43. void __Startup__() {
  44.     main();
  45.     }
  46.  
  47. // * ******************************************************************************* *
  48. // * ******************************************************************************* *
  49.  
  50. void main() {
  51.     long saveA4 = SetCurrentA4();
  52.     Boolean isNative;
  53.     short procID;
  54.     long response;
  55.     Handle procHandle;
  56.     Str255 textBuff, errBuff;
  57.  
  58.     // Determine the environment and prepare our code
  59.     if (Gestalt(gestaltSystemVersion, &response) || (response < 0x0604)) goto END;
  60.     
  61.     // Of course, certain 68K machines don't know this selector, 
  62.     //   so just wimp out if Gestalt returns an error.
  63.     if (Gestalt(gestaltNativeCPUtype, &response)) isNative = FALSE;
  64.       else switch(response) {
  65.         /* Various 68k CPUs...     */
  66.         case gestaltCPU68000:    // 0x0001
  67.         case gestaltCPU68010:    // 0x0002
  68.         case gestaltCPU68020:    // 0x0003
  69.         case gestaltCPU68030:    // 0x0004
  70.         case gestaltCPU68040:    // 0x0005
  71.             isNative = FALSE;
  72.             break;
  73.         /* PPC 601                */
  74.         case gestaltCPU601:        // 0x0101
  75.         case gestaltCPU603:        // 0x0103
  76.         case gestaltCPU604:        // 0x0104
  77.             isNative = TRUE;
  78.             break;
  79.         /* Anything Else...     */
  80.         default:
  81.             isNative = FALSE;
  82.             break;
  83.         }
  84.  
  85.     // Get information about *this* resource, because we want to load the 
  86.     //   PPC or the 68K resource with the same ID for consistency.
  87.     procHandle = RecoverHandle((Ptr) __Startup__);
  88.     if (!procHandle || ResError()) goto END;
  89.     
  90.     GetResInfo(procHandle, &procID, (ResType *) &response, textBuff);
  91.     if (ResError()) goto END;
  92.     
  93. #ifdef ____DEBUG____
  94.     DebugStr("¥pINIT Dispatcher... kewl!");
  95. #endif ____DEBUG____
  96.     if (isNative && (procHandle = Get1Resource(kPPCProcType, procID))) {
  97.         RoutineDescriptor rd = BUILD_ROUTINE_DESCRIPTOR(uppINITProcInfo, 0);
  98.         RoutineDescriptorPtr rdPtr = &rd;
  99.         ConnectionID cfmConnID;
  100.         ProcPtr procPtr = 0;
  101.  
  102.         // Prepare for execution by finding or building a routine descriptor
  103.         HLockHi(procHandle);
  104.         if (**(short **) procHandle == _MixedModeMagic) procPtr = (ProcPtr) *procHandle;
  105.           else if (! GetMemFragment(*procHandle, GetHandleSize(procHandle),
  106.                 textBuff, kLoadNewCopy, &cfmConnID, (Ptr *) &procPtr, errBuff)) {
  107.  
  108.             // The way MixedMode.h is structured, the current ISA gets set to 68k
  109.             //   We need override this for our upcoming procedure... so override it.
  110.             rd.routineRecords[0].ISA = ((ISAType) kPowerPCISA) | ((RTAType) kPowerPCRTA);
  111.             rd.routineRecords[0].procDescriptor = procPtr;
  112.             }
  113.  
  114.         if (procPtr) {
  115.             SetA4(saveA4);
  116.             CallINITProc(rdPtr);
  117.             saveA4 = SetCurrentA4();
  118.             
  119.             // Normally we would close the CFM Connection... but we want it to
  120.             //   live if the rsrc Handle was detached and is still hanging around.
  121.             if (procHandle == Get1Resource(kPPCProcType, procID)) CloseConnection(&cfmConnID);
  122.             
  123.             // Skip over the 68k boring stuff... we're done!
  124.             goto END;
  125.             }
  126.         
  127.         // Something went wrong w/ PPC resource... we'll clean up and try 68K
  128.         HUnlock(procHandle);
  129.         ReleaseResource(procHandle);
  130.         }
  131.     
  132.     // If we don't run the PPC code (either by intention or error), then
  133.     //   we can alway fall back on friendly 68K code... and it's easy too!
  134.     if (procHandle = Get1Resource(k68KProcType, procID)) {
  135.         HLockHi(procHandle);
  136.         SetA4(saveA4);
  137.         CallINITProc(*procHandle);
  138.         saveA4 = SetCurrentA4();
  139.         }
  140.             
  141. END:
  142.     SetA4(saveA4);
  143.     }
  144.  
  145.